using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.ServiceProcess;
using System.Xml;
using Microsoft.Win32;
using wandev.AutoUpdate;
using System.Reflection;
using wandev.AutoUpdate.Forms;
using System.Diagnostics;

namespace Emlyn.Applications.Servant
{
	public class frmServant : System.Windows.Forms.Form
	{
		private System.Windows.Forms.NotifyIcon notifyMain;
		private System.Windows.Forms.ContextMenuStrip pmenRight;
		private System.Windows.Forms.ToolStripMenuItem menuExit;
		private System.Windows.Forms.Panel panel2;
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.Button button1;
		private System.Windows.Forms.Button button2;
		private System.Windows.Forms.ListView listView1;
		private System.Windows.Forms.ColumnHeader ConfiguredServices;
		private System.ServiceProcess.ServiceController serviceController1;
		private System.Windows.Forms.ContextMenuStrip pmenService;
		private System.Windows.Forms.Button btnMoveUp;
		private System.Windows.Forms.Button btnMoveDown;
		private System.Windows.Forms.ImageList imageList1;
		private System.Windows.Forms.CheckBox cbAutorun;
		private System.Windows.Forms.ToolStripMenuItem menuConfigure;
		private System.Windows.Forms.Button btnDelete;
        private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem1;
        private ToolStripMenuItem menuAbout;
        private ToolStripMenuItem menuUpdates;
		private System.ComponentModel.IContainer components;

		public frmServant()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmServant));
            this.notifyMain = new System.Windows.Forms.NotifyIcon(this.components);
            this.pmenRight = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.menuConfigure = new System.Windows.Forms.ToolStripMenuItem();
            this.menuUpdates = new System.Windows.Forms.ToolStripMenuItem();
            this.menuAbout = new System.Windows.Forms.ToolStripMenuItem();
            this.menuExit = new System.Windows.Forms.ToolStripMenuItem();
            this.pmenService = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.ToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
            this.panel2 = new System.Windows.Forms.Panel();
            this.btnDelete = new System.Windows.Forms.Button();
            this.cbAutorun = new System.Windows.Forms.CheckBox();
            this.btnMoveDown = new System.Windows.Forms.Button();
            this.btnMoveUp = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button1 = new System.Windows.Forms.Button();
            this.panel1 = new System.Windows.Forms.Panel();
            this.listView1 = new System.Windows.Forms.ListView();
            this.ConfiguredServices = new System.Windows.Forms.ColumnHeader();
            this.serviceController1 = new System.ServiceProcess.ServiceController();
            this.imageList1 = new System.Windows.Forms.ImageList(this.components);
            this.pmenRight.SuspendLayout();
            this.pmenService.SuspendLayout();
            this.panel2.SuspendLayout();
            this.panel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // notifyMain
            // 
            this.notifyMain.ContextMenuStrip = this.pmenRight;
            this.notifyMain.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyMain.Icon")));
            this.notifyMain.Text = "Servant";
            this.notifyMain.Click += new System.EventHandler(this.notifyMain_Click);
            this.notifyMain.DoubleClick += new System.EventHandler(this.notifyMain_DoubleClick);
            this.notifyMain.MouseDown += new System.Windows.Forms.MouseEventHandler(this.notifyMain_MouseDown);
            // 
            // pmenRight
            // 
            this.pmenRight.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.menuConfigure,
            this.menuUpdates,
            this.menuAbout,
            this.menuExit});
            this.pmenRight.Name = "pmenRight";
            this.pmenRight.Size = new System.Drawing.Size(175, 92);
            this.pmenRight.Opened += new System.EventHandler(this.pmenRight_Popup);
            // 
            // menuConfigure
            // 
            this.menuConfigure.MergeIndex = 0;
            this.menuConfigure.Name = "menuConfigure";
            this.menuConfigure.Size = new System.Drawing.Size(174, 22);
            this.menuConfigure.Text = "Configure...";
            this.menuConfigure.Click += new System.EventHandler(this.menuConfigure_Click);
            // 
            // menuUpdates
            // 
            this.menuUpdates.Name = "menuUpdates";
            this.menuUpdates.Size = new System.Drawing.Size(174, 22);
            this.menuUpdates.Text = "Check for Updates";
            this.menuUpdates.Click += new System.EventHandler(this.menuUpdates_Click);
            // 
            // menuAbout
            // 
            this.menuAbout.Name = "menuAbout";
            this.menuAbout.Size = new System.Drawing.Size(174, 22);
            this.menuAbout.Text = "About";
            this.menuAbout.Click += new System.EventHandler(this.menuAbout_Click);
            // 
            // menuExit
            // 
            this.menuExit.MergeIndex = 1;
            this.menuExit.Name = "menuExit";
            this.menuExit.Size = new System.Drawing.Size(174, 22);
            this.menuExit.Text = "E&xit Servant";
            this.menuExit.Click += new System.EventHandler(this.menuExit_Click);
            // 
            // pmenService
            // 
            this.pmenService.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.ToolStripMenuItem1});
            this.pmenService.Name = "pmenService";
            this.pmenService.Size = new System.Drawing.Size(117, 26);
            this.pmenService.Opening += new System.ComponentModel.CancelEventHandler(this.pmenService_Opening);
            // 
            // ToolStripMenuItem1
            // 
            this.ToolStripMenuItem1.MergeIndex = 0;
            this.ToolStripMenuItem1.Name = "ToolStripMenuItem1";
            this.ToolStripMenuItem1.Size = new System.Drawing.Size(116, 22);
            this.ToolStripMenuItem1.Text = "&Delete";
            this.ToolStripMenuItem1.Click += new System.EventHandler(this.ToolStripMenuItem1_Click);
            // 
            // panel2
            // 
            this.panel2.Controls.Add(this.btnDelete);
            this.panel2.Controls.Add(this.cbAutorun);
            this.panel2.Controls.Add(this.btnMoveDown);
            this.panel2.Controls.Add(this.btnMoveUp);
            this.panel2.Controls.Add(this.button2);
            this.panel2.Controls.Add(this.button1);
            this.panel2.Dock = System.Windows.Forms.DockStyle.Right;
            this.panel2.Location = new System.Drawing.Point(304, 0);
            this.panel2.Name = "panel2";
            this.panel2.Size = new System.Drawing.Size(96, 289);
            this.panel2.TabIndex = 2;
            // 
            // btnDelete
            // 
            this.btnDelete.Location = new System.Drawing.Point(8, 36);
            this.btnDelete.Name = "btnDelete";
            this.btnDelete.Size = new System.Drawing.Size(80, 23);
            this.btnDelete.TabIndex = 6;
            this.btnDelete.Text = "&Delete";
            this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
            // 
            // cbAutorun
            // 
            this.cbAutorun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.cbAutorun.Location = new System.Drawing.Point(8, 228);
            this.cbAutorun.Name = "cbAutorun";
            this.cbAutorun.Size = new System.Drawing.Size(80, 24);
            this.cbAutorun.TabIndex = 5;
            this.cbAutorun.Text = "Auto Run";
            // 
            // btnMoveDown
            // 
            this.btnMoveDown.Location = new System.Drawing.Point(8, 92);
            this.btnMoveDown.Name = "btnMoveDown";
            this.btnMoveDown.Size = new System.Drawing.Size(80, 23);
            this.btnMoveDown.TabIndex = 3;
            this.btnMoveDown.Text = "Move &Down";
            this.btnMoveDown.Click += new System.EventHandler(this.btnMoveDown_Click);
            // 
            // btnMoveUp
            // 
            this.btnMoveUp.Location = new System.Drawing.Point(8, 64);
            this.btnMoveUp.Name = "btnMoveUp";
            this.btnMoveUp.Size = new System.Drawing.Size(80, 23);
            this.btnMoveUp.TabIndex = 2;
            this.btnMoveUp.Text = "Move &Up";
            this.btnMoveUp.Click += new System.EventHandler(this.btnMoveUp_Click);
            // 
            // button2
            // 
            this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.button2.Location = new System.Drawing.Point(8, 260);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(80, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "&Close";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(8, 8);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(80, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "&Add...";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // panel1
            // 
            this.panel1.Controls.Add(this.listView1);
            this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(304, 289);
            this.panel1.TabIndex = 4;
            // 
            // listView1
            // 
            this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.ConfiguredServices});
            this.listView1.ContextMenuStrip = this.pmenService;
            this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.listView1.Location = new System.Drawing.Point(0, 0);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(304, 289);
            this.listView1.TabIndex = 0;
            this.listView1.UseCompatibleStateImageBehavior = false;
            this.listView1.View = System.Windows.Forms.View.Details;
            this.listView1.DragDrop += new System.Windows.Forms.DragEventHandler(this.listView1_DragDrop);
            this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
            this.listView1.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.listView1_ItemDrag);
            // 
            // ConfiguredServices
            // 
            this.ConfiguredServices.Text = "Services";
            this.ConfiguredServices.Width = 297;
            // 
            // imageList1
            // 
            this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
            this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
            this.imageList1.Images.SetKeyName(0, "");
            this.imageList1.Images.SetKeyName(1, "");
            this.imageList1.Images.SetKeyName(2, "");
            this.imageList1.Images.SetKeyName(3, "");
            this.imageList1.Images.SetKeyName(4, "");
            // 
            // frmServant
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(400, 289);
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.panel2);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MinimumSize = new System.Drawing.Size(280, 210);
            this.Name = "frmServant";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Servant";
            this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
            this.Closed += new System.EventHandler(this.frmServant_Closed);
            this.Resize += new System.EventHandler(this.Form1_Resize);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.pmenRight.ResumeLayout(false);
            this.pmenService.ResumeLayout(false);
            this.panel2.ResumeLayout(false);
            this.panel1.ResumeLayout(false);
            this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args) 
		{
			frmServant frm = new frmServant();
			frm.WindowState = FormWindowState.Minimized;

            if (args.Length > 0 && args[0].ToUpper() == "/RESTART")
            {
                Process.Start(Application.ExecutablePath);
            }
            else
            {
                frm.notifyMain.Visible = true; // show the icon here

                frm.LoadSettings(false);
                if (!frm.CheckForUpdatesAndUpdateIfNecessary())
                {
                    if (args.Length > 0 && args[0].ToUpper() == "/INSTALL")
                    {
                        frm.notifyMain.Visible = false;
                        System.Diagnostics.Process.Start(InstallFolder() + "\\Servant.exe");
                    }
                    else if (args.Length > 0 && args[0].ToUpper() == "/UNINSTALL")
                    {
                        frm.notifyMain.Visible = false;
                        frm.ClearAutorun();
                    }
                    else
                    {
                        if (frm.cbAutorun.Checked)
                            frm.SetAutorun();
                        else
                            frm.ClearAutorun();
                        Application.Run(frm);
                    }
                }
            }
		}

        private string _ignoreRemoteVersionCode = null;

		private static string InstallFolder()
		{
			return System.AppDomain.CurrentDomain.BaseDirectory;
		}

		private void Form1_Resize(object sender, System.EventArgs e)
		{
			if (FormWindowState.Minimized == WindowState)
			{
				ShowInTaskbar = false;
				Hide();
			}
		}

		private void notifyMain_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
		
		}

		private void notifyMain_DoubleClick(object sender, System.EventArgs e)
		{
			Show();
			WindowState = FormWindowState.Normal;
			ShowInTaskbar = true;
		}

		private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = WindowState != FormWindowState.Minimized;
			WindowState = FormWindowState.Minimized;
		}

		private void notifyMain_Click(object sender, System.EventArgs e)
		{
		}

		private void menuExit_Click(object sender, System.EventArgs e)
		{
			WindowState = FormWindowState.Minimized;
			Close();
		}

		private void menuStart(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = GetServiceForParentToolStripMenuItem(sender as ToolStripMenuItem);

			if (lslvi != null)
			{
				try
				{
					lslvi.Service.Start();
				}
				catch{};
			}
		}

		private void menuStop(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = GetServiceForParentToolStripMenuItem(sender as ToolStripMenuItem);

			if (lslvi != null)
			{
				try
				{
					lslvi.Service.Stop();
				}
				catch{};
			}
		}
		private void menuPause(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = GetServiceForParentToolStripMenuItem(sender as ToolStripMenuItem);

			if (lslvi != null)
			{
				try
				{
					lslvi.Service.Pause();
				}
				catch{};
			}
		}
		private void menuContinue(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = GetServiceForParentToolStripMenuItem(sender as ToolStripMenuItem);

			if (lslvi != null)
			{
				try
				{
					lslvi.Service.Continue();
				}
				catch{};
			}
		}

        private void menuRestart(object sender, System.EventArgs e)
        {
            ServiceListViewItem lslvi = GetServiceForParentToolStripMenuItem(sender as ToolStripMenuItem);

            if (lslvi != null)
            {
                try
                {
                    lslvi.Service.Stop();
                    lslvi.Service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 10));
                    lslvi.Service.Start();
                }
                catch { };
            }
        }
        
        private void button2_Click(object sender, System.EventArgs e)
		{
			WindowState = FormWindowState.Minimized;
		}

        private void UpdateIcons()
        {

        }

        private void CreateContextMenu()
        {
            ToolStripMenuItem litem = null;

            pmenRight.Items.Clear();

            foreach (ServiceListViewItem lslvi in listView1.Items)
            {
                try
                {
                    ServiceController lservice = lslvi.Service;

                    lservice.Refresh();

                    litem = new ToolStripMenuItem(
                        lservice.DisplayName + ": " + lservice.Status.ToString()
                        );

                    lslvi.ServiceMenuItem = litem;
                    pmenRight.Items.Add(litem);


                    // now add the appropriate controls for each item
                    bool lneedStop = false;
                    bool lneedPause = false;
                    bool lneedContinue = false;
                    bool lneedStart = false;
                    bool lneedRestart = false;

                    if (lservice.Status == ServiceControllerStatus.Running)
                    {
                        lneedStop = true;
                        lneedPause = true;
                        lneedRestart = true;
                    }
                    else if (lservice.Status == ServiceControllerStatus.Stopped)
                    {
                        lneedStart = true;
                    }
                    else if (lservice.Status == ServiceControllerStatus.Paused)
                    {
                        lneedContinue = true;
                        lneedStop = true;
                    };

                    ToolStripMenuItem lsubMenuItem;

                    if (lneedStart)
                    {
                        lsubMenuItem = new ToolStripMenuItem(
                            "Start"
                            );
                        lsubMenuItem.Click += new System.EventHandler(menuStart);

                        litem.DropDownItems.Add(lsubMenuItem);
                    }
                    if (lneedStop)
                    {
                        lsubMenuItem = new ToolStripMenuItem(
                            "Stop"
                            );
                        lsubMenuItem.Click += new System.EventHandler(menuStop);

                        litem.DropDownItems.Add(lsubMenuItem);
                    }
                    if (lneedPause)
                    {
                        lsubMenuItem = new ToolStripMenuItem(
                            "Pause"
                            );

                        lsubMenuItem.Click += new System.EventHandler(menuPause);

                        litem.DropDownItems.Add(lsubMenuItem);
                    }
                    if (lneedContinue)
                    {
                        lsubMenuItem = new ToolStripMenuItem(
                            "Continue"
                            );

                        lsubMenuItem.Click += new System.EventHandler(menuContinue);

                        litem.DropDownItems.Add(lsubMenuItem);
                    }

                    if (lneedRestart)
                    {
                        lsubMenuItem = new ToolStripMenuItem(
                            "Restart"
                            );

                        lsubMenuItem.Click += new System.EventHandler(menuRestart);

                        litem.DropDownItems.Add(lsubMenuItem);
                    }
                }
                catch (InvalidOperationException ioex)
                {
                    // the service has dissapeared
                    // just ignore this and move on
                }
            }

            if (listView1.Items.Count > 0)
            {
                pmenRight.Items.Add(new ToolStripSeparator());
            }

            litem = new ToolStripMenuItem(
                "Configure..."
                );
            litem.Click += new System.EventHandler(menuConfigure_Click);
            pmenRight.Items.Add(litem);

            litem = new ToolStripMenuItem(
                "Check for Updates"
                );
            litem.Click += new System.EventHandler(menuUpdates_Click);
            pmenRight.Items.Add(litem);

            litem = new ToolStripMenuItem(
                "About Servant"
                );
            litem.Click += new System.EventHandler(menuAbout_Click);
            pmenRight.Items.Add(litem);

            litem = new ToolStripMenuItem(
                "Exit Servant"
                );
            litem.Click += new System.EventHandler(menuExit_Click);
            pmenRight.Items.Add(litem);
        }



		private ServiceListViewItem GetServiceForToolStripMenuItem(ToolStripMenuItem ToolStripMenuItem)
		{
			foreach(ServiceListViewItem lslvi in listView1.Items)
			{
				if (lslvi.ServiceMenuItem == ToolStripMenuItem)
					return lslvi;
			};

			return null;
		}

		private ServiceListViewItem GetServiceForParentToolStripMenuItem(ToolStripMenuItem ToolStripMenuItem)
		{
			if (ToolStripMenuItem != null && ToolStripMenuItem.OwnerItem != null)
				return GetServiceForToolStripMenuItem(ToolStripMenuItem.OwnerItem as ToolStripMenuItem);
			else
				return null;
		}


		private void pmenRight_Popup(object sender, System.EventArgs e)
		{
            try
            {
			    CreateContextMenu();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
		}

		private void button1_Click(object sender, System.EventArgs e)
		{
			ServiceController lservice = frmAllServices.Execute();

			if (lservice != null)
			{
				ServiceListViewItem lslvi = new ServiceListViewItem();
				
				lslvi.Text = lservice.DisplayName;
				lslvi.Service = lservice;

				listView1.Items.Add(lslvi);
			}
		}

		private void ToolStripMenuItem1_Click(object sender, System.EventArgs e)
		{
			DeleteSelected();
		}

		private void listView1_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
		{
		}

		private void listView1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
		{
		}

		public void UpdateButtons()
		{
			bool lMoveUpEnabled = false;
			bool lMoveDownEnabled = false;
			bool lDeleteEnabled = false;

			if (listView1.SelectedIndices.Count > 0)
			{
				lDeleteEnabled = true;
				lMoveUpEnabled = listView1.SelectedIndices[0] > 0;
				lMoveDownEnabled = listView1.SelectedIndices[0] < (listView1.Items.Count-1);
			}

			btnDelete.Enabled = lDeleteEnabled;
			btnMoveUp.Enabled = lMoveUpEnabled;
			btnMoveDown.Enabled = lMoveDownEnabled;
		}

		private void listView1_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			UpdateButtons();
		}

		private void btnMoveUp_Click(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = SelectedServiceListViewItem;

			if (lslvi != null)
			{
				int lslviIndex = listView1.Items.IndexOf(lslvi);

				listView1.Items.Remove(lslvi);

				listView1.Items.Insert(lslviIndex-1, lslvi);
			}
		}

		private void btnMoveDown_Click(object sender, System.EventArgs e)
		{
			ServiceListViewItem lslvi = SelectedServiceListViewItem;

			if (lslvi != null)
			{
				int lslviIndex = listView1.Items.IndexOf(lslvi);

				listView1.Items.Remove(lslvi);

				listView1.Items.Insert(lslviIndex+1, lslvi);
			}
		}

		public ServiceListViewItem SelectedServiceListViewItem
		{
			get
			{
				ServiceListViewItem lslvi = null;

				if (listView1.SelectedItems.Count > 0)
					lslvi = listView1.SelectedItems[0] as ServiceListViewItem;

				return lslvi;
			}
		}

		public void LoadSettings(bool aShowExceptions)
		{
			// defaults
			listView1.Items.Clear();
			cbAutorun.Checked = true;

			// now load
			try
			{
				XmlDocument ldoc = new XmlDocument();
				using (System.IO.StreamReader sr = System.IO.File.OpenText(InstallFolder() + "\\Servant.xml"))
				{
					ldoc.Load(sr);

					XmlNode lnode = null;
					XmlNode lrootNode = ldoc.SelectSingleNode("Servant");
					if (lrootNode != null)
						lnode = lrootNode.SelectSingleNode("Services");

					if (lnode != null)
					{
						foreach(XmlNode lsubNode in lnode.ChildNodes)
						{
                            try
                            {
                                ServiceController lsc = new ServiceController(
                                    lsubNode.InnerText.Trim()
                                    );
                                lsc.Refresh();

                                ServiceListViewItem lslvi = new ServiceListViewItem();

                                lslvi.Text = lsc.DisplayName;
                                lslvi.Service = lsc;
                                listView1.Items.Add(lslvi);
                            }
                            catch
                            {
                                // something went wrong while loading this item, ignore it
                            }
						}
					}

					lnode = null;
					if (lrootNode != null)
						lnode = lrootNode.SelectSingleNode("Config");

					if (lnode != null)
					{
						XmlNode lautoRun = lnode.SelectSingleNode("AutoRun");

						if (lautoRun != null)
						{
							cbAutorun.Checked = lautoRun.InnerText.Trim() == "true";
						}

                        XmlNode lignoreRemoteVersionCode = lnode.SelectSingleNode("IgnoreRemoteVersionCode");

                        if (lignoreRemoteVersionCode != null)
                        {
                            _ignoreRemoteVersionCode = lignoreRemoteVersionCode.InnerText.Trim();
                        }
                    }
				}
			}
			catch (Exception ex)
			{
                if (aShowExceptions)
                    MessageBox.Show(ex.ToString());
			}
		}

		public void SaveSettings(bool aShowExceptions)
		{
            try
            {
                XmlDocument ldoc = new XmlDocument();

                XmlElement lservant = ldoc.CreateElement("Servant");
                ldoc.AppendChild(lservant);
                XmlElement lservices = ldoc.CreateElement("Services");
                lservant.AppendChild(lservices);

                int t = 0;
                foreach (ServiceListViewItem lslvi in listView1.Items)
                {
                    XmlElement lservice = ldoc.CreateElement("s" + t.ToString());
                    lservice.InnerText = lslvi.Service.ServiceName;
                    lservices.AppendChild(lservice);
                    t++;
                }

                XmlElement lconfig = ldoc.CreateElement("Config");
                lservant.AppendChild(lconfig);

                XmlElement lautoRun = ldoc.CreateElement("AutoRun");
                lautoRun.InnerText = cbAutorun.Checked ? "true" : "false";
                lconfig.AppendChild(lautoRun);

                XmlElement lignoreRemoteVersionCode = ldoc.CreateElement("IgnoreRemoteVersionCode");
                lignoreRemoteVersionCode.InnerText = _ignoreRemoteVersionCode;
                lconfig.AppendChild(lignoreRemoteVersionCode);

                ldoc.Save(InstallFolder() + "Servant.xml");
            }
            catch (Exception ex)
            {
                if (aShowExceptions)
                    MessageBox.Show(ex.ToString());
            }
		}

		private void frmServant_Closed(object sender, System.EventArgs e)
		{
			SaveSettings(false);
			if (cbAutorun.Checked)
				SetAutorun();
			else
				ClearAutorun();
		}

		public void SetAutorun()
		{
			try
			{
				using (RegistryKey lregKey = Registry.LocalMachine.CreateSubKey(
						   "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
						   ))
				{
					lregKey.SetValue("Servant", "\"" + InstallFolder() + "\\Servant.exe\"");
				}
			}
			catch
			{
				// do nothing
			}
		}

		public void ClearAutorun()
		{
			try
			{
				using (RegistryKey lregKey = Registry.LocalMachine.CreateSubKey(
						   "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
						   ))
				{
					lregKey.DeleteValue("Servant", false);
				}
			}
			catch
			{
				// do nothing
			}
		}

		private void ToolStripMenuItem2_Click(object sender, System.EventArgs e)
		{
		}

		private void menuConfigure_Click(object sender, System.EventArgs e)
		{
			Show();
			WindowState = FormWindowState.Normal;
		}

		private void btnDelete_Click(object sender, System.EventArgs e)
		{
			DeleteSelected();
		}

		private void DeleteSelected()
		{
			ServiceListViewItem lslvi = SelectedServiceListViewItem;

			if (lslvi != null)
			{
				listView1.Items.Remove(lslvi);
			}
		}

        private void pmenService_Opening(object sender, CancelEventArgs e)
        {

        }

        const string _appName = "Servant";
        const string _versionurl = "http://emlynoregan.com/ServantVersions.xml";
        const string _productCode = "{FE10CA83-9389-44EE-82A8-1D4BCDCE37BF}";

        private static RemoteLatestVersion GetNewRemoteLatestVersion()
        {
            return new RemoteLatestVersion(new Uri(_versionurl), _appName);
        }

        private static string GetCurrentVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        private void menuAbout_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Servant v" + GetCurrentVersion() + Environment.NewLine + "by Emlyn O'Regan" + Environment.NewLine + "http://emlynoregan.com");
        }

        private void menuUpdates_Click(object sender, EventArgs e)
        {
            try
            {
                RemoteLatestVersion lrlv = GetNewRemoteLatestVersion();

                lrlv.GetLatestVersionInformation();

                if (lrlv.LatestVersion.VersionNumber == GetCurrentVersion())
                    MessageBox.Show("Servant is up to date");
                else
                {
                    UpdateToNewVersion(lrlv);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private bool CheckForUpdatesAndUpdateIfNecessary()
        {
            bool retval = false;

            try
            {
                RemoteLatestVersion lrlv = GetNewRemoteLatestVersion();

                lrlv.GetLatestVersionInformation();

                bool ldoUpdate;

                ldoUpdate = lrlv.LatestVersion.VersionNumber != GetCurrentVersion();

                if (ldoUpdate && !String.IsNullOrEmpty(_ignoreRemoteVersionCode))
                    ldoUpdate = lrlv.LatestVersion.VersionNumber != _ignoreRemoteVersionCode;

                if (ldoUpdate)
                {
                    retval = UpdateToNewVersion(lrlv);
                }
            }
            catch
            {
                // this method is explicitly silent regarding exceptions
            }

            return retval;
        }

        private bool UpdateToNewVersion(RemoteLatestVersion arlv)
        {
            bool retval = false;
            string lnewVersion = arlv.LatestVersion.VersionNumber;
            
            DialogResult ldialogResult = frmUpdateAvailable.PromptForUpdate(GetCurrentVersion(), lnewVersion);

            if (ldialogResult == DialogResult.Yes)
            {
                NewVersionDownloader.DownloadNewVersion(arlv.LatestVersion);

                if (arlv.LatestVersion.LocalFileExistsAndIsCorrectSize)
                {
                    VersionRunner.Run(arlv.LatestVersion, _productCode);
                    Close();
                    retval = true;
                }
            }
            else if (ldialogResult == DialogResult.No)
            {
                _ignoreRemoteVersionCode = lnewVersion;
            }

            return retval;
        }
	}
}
